
#include <iostream>
#include <string>
#include <vector>
#include <mutex>

using namespace std;

// -std=c++0x
//g++  -o "$(CURRENT_DIRECTORY)\bin\$(NAME_PART).exe" "$(FULL_CURRENT_PATH)"  -std=c++17 -w -finput-charset=utf-8 -fexec-charset=gbk
// 因为 mutex 的问题，编译不了
// 这里有解决方案, 不过windows下，还是改成 boost::mutex吧
// http://blog.itjsz.com/windows-%E7%BC%96%E8%AF%91-c-%E6%8A%A5%E9%94%99-error-mutex-in-namespace-std-does-not-name-a-type/

// 抽象享元类
class NetDevice
{
public:
	NetDevice(){}
	virtual string getName() = 0;
 
	void print(){
		printf("NetDevice :%s\n",getName().c_str());
	}
};

// 具体享元类:集线器
class Hub :public NetDevice
{
public:
	Hub(){}
	string getName(){
		return "集线器";
	}
};
 
// 具体享元类:交换机
class Switch :public NetDevice
{
public:
	Switch(){}
	string getName(){
		return "交换机";
	}
};


// 享元工厂类
class NetDeviceFactory
{
public:
	NetDevice* getNetDevice(char ch){
		if (ch == 'S'){
			return devicePool[1];
		}
		else if (ch == 'H'){
			return devicePool[0];
		}
		else{
			printf("wrong input!\n");
		}
		return NULL;
	}
public:
	// 单例模式：返回享元工厂类的唯一实例
	static NetDeviceFactory* getFactory(){
		if (instance == NULL){
			printf("instance is Null\n");
			// m_mutex.lock();
			if (instance == NULL){
				instance = new NetDeviceFactory();
			}
			// m_mutex.unlock();
		}else{
			printf("instance: %08x\n", &instance);
		}
		return instance;
	}

private:
	NetDeviceFactory(){
		Hub *hub = new Hub();
		Switch *switcher = new Switch();
		devicePool.push_back(hub);
		devicePool.push_back(switcher);
	}
 
	// 共享池：用一个vector来表示
	vector<NetDevice*> devicePool;
public:
	static NetDeviceFactory* instance;
	// static mutex m_mutex;
};

NetDeviceFactory* NetDeviceFactory::instance = NULL;
// mutex NetDeviceFactory::m_mutex;

int main()
{
	NetDeviceFactory *factory = NetDeviceFactory::getFactory();
 
	NetDevice *device1, *device2, *device3, *device4;
 
	// 客户端1获取一个hub
	device1 = factory->getNetDevice('H');
	device1->print();
	// 客户端2获取一个hub
	device2 = factory->getNetDevice('H');
	device2->print();
	// 判断两个hub是否是同一个
	printf("判断两个hub是否是同一个:\n");
	printf("device1:%p\ndevice2:%p\n", device1, device2);
 
	printf("\n\n\n\n");
	// 客户端3获取一个switch
	device3 = factory->getNetDevice('S');
	device3->print();
	// 客户端4获取一个switch
	device4 = factory->getNetDevice('S');
	device4->print();
	// 判断两个switch是否是同一个
	printf("判断两个switch是否是同一个:\n");
	printf("device3:%p\ndevice4:%p\n", device3, device4);
 
	printf("\n\n");
	printf("factory: %08x\n", &factory);
	NetDeviceFactory* obj = NetDeviceFactory::getFactory();
	printf("obj: %08x\n", &obj);
	
	
	NetDevice *device5, *device6, *device7, *device8;
	device5 = obj->getNetDevice('H');
	device5->print();
	// 判断两个hub是否是同一个
	printf("判断两个hub是否是同一个:\n");
	printf("device1:%p\ndevice5:%p\n", device1, device5);
	
 
	return 0;
}





